package com.xyzboom.compiler.fa

class NFANode<T, K>(
    val value: T,
    val next: MutableMap<FAEdge<K>?, MutableSet<NFANode<T, K>>>
) {
    constructor(value: T) : this(value, HashMap())

    override fun toString(): String {
        return "Node(value=$value)"
    }

    override fun equals(other: Any?): Boolean {
        if (this === other) return true
        if (other !is NFANode<*, *>) return false

        if (value != other.value) return false

        return true
    }

    override fun hashCode(): Int {
        return value?.hashCode() ?: 0
    }

    //<editor-fold desc="Node Methods">


    fun addNext(c: FAEdge<K>?, node: NFANode<T, K>) {
        next.getOrPut(c) { HashSet() }.add(node)
    }

    fun resetNext(c: FAEdge<K>?, node: NFANode<T, K>) {
        next.clear()
        addNext(c, node)
    }

    fun addAllNext(set: MutableSet<FAEdge<K>?>, node: NFANode<T, K>) {
        for (c in set) {
            addNext(c, node)
        }
    }

    fun resetAllNext(set: MutableSet<FAEdge<K>?>, node: NFANode<T, K>) {
        next.clear()
        addAllNext(set, node)
    }

    fun addCopyNext(node: NFANode<T, K>) {
        node.next.forEach {
            next.getOrPut(it.key) { HashSet() }.addAll(it.value)
        }
    }

    fun resetAndCopyNext(node: NFANode<T, K>) {
        next.clear()
        addCopyNext(node)
    }
    //</editor-fold>
}